package com.mobile.check.activitys;

import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cn.droidlover.xdroidmvp.kit.NLog;
import cn.droidlover.xdroidmvp.kit.NToast;
import cn.droidlover.xdroidmvp.mvp.XActivity;
import com.mobile.check.beans.BluetoothInfo;
import com.mobile.check.app.R;
import com.mobile.check.present.BasePresent;
import com.mobile.check.bluetooth.BluetoothCtrl;
import com.mobile.check.bluetooth.BluetoothSppClient;

public class ReceiveDataActivity extends XActivity<BasePresent> implements View.OnClickListener {
    private static final String DETECTOR_FID = "detector fid";
    private static final String DETECTOR_PID = "detector pid";
    private static final String IGNITE_FID = "ignite";
    private static final String LOG_START = "log start";
    private static final String PUMP_OFF = "pump off";
    private static final String PUMP_ON = "pump on";
    private static final String PUSH_1 = "push 1";
    private static final String PUSH_EX = "push ex";
    private static final String QUIT = "quit";
    private static final String SCREEN = "screen";

    BluetoothInfo bluetoothInfo;
    @BindView(R.id.actMain_tv_device_info)
    TextView actMainTvDeviceInfo;
    @BindView(R.id.actMain_tv_service_uuid)
    TextView mtvServiceUUID;
    @BindView(R.id.actMain_btn_pair)
    Button mbtnPair;
    @BindView(R.id.actMain_btn_conn)
    Button mbtnComm;
    @BindView(R.id.receiveTv)
    TextView receiveTv;
    @BindView(R.id.actKeyBoard_ll_ctrl_area)
    LinearLayout actKeyBoard_ll_ctrl_area;

    private Handler mHandler;

    private ProgressDialog mProgressDialog;
    /**
     * 常量:结束符字符集
     */
    protected final static String[] msEND_FLGS = {"\r\n", "\n"};
    String msEndFlg;
    /**
     * 线程终止标志(用于终止监听线程)
     */
    protected boolean mbThreadStop = false;
    /**
     * 蓝牙设备连接句柄
     */
    private BluetoothDevice mBDevice = null;
    /**
     * 获取到的UUID Service 列表信息
     */
    private ArrayList<String> mslUuidList = new ArrayList<String>();
    /**
     * 手机的蓝牙适配器
     */
    private BluetoothAdapter mBT = BluetoothAdapter.getDefaultAdapter();
    /**
     * 全局静态对象池
     */
    private GlobalPoolApplication mGP = null;
    protected BluetoothSppClient mBSC = null;
    /**
     * 输入模式
     */
    protected byte mbtInputMode = BluetoothSppClient.IO_MODE_STRING;
    /**
     * 输出模式
     */
    protected byte mbtOutputMode = BluetoothSppClient.IO_MODE_STRING;
    /**
     * 蓝牙配对进程操作标志
     */
    private boolean mbBonded = false;


    @Override
    public void getDataFromServer() {
    }

    @Override
    public int getContentViewId() {
        return R.layout.activity_receivedata;
    }

    @Override
    public void initData(Bundle savedInstanceState) {
        super.initData(savedInstanceState);
        mHandler = new Handler();
    }

    @Override
    public void initView() {
        super.initView();
        titleTv.setText("蓝牙连接");
        this.mGP = ((GlobalPoolApplication) this.getApplicationContext()); //得到全局对象的引用
        this.mBSC = ((GlobalPoolApplication) this.getApplicationContext()).mBSC;

        //如果设备未配对，显示配对操作
        if (bluetoothInfo.getBond().equals(getString(R.string.actDiscovery_bond_nothing))) {
            this.mbtnPair.setVisibility(View.VISIBLE); //显示配对按钮
            this.mbtnComm.setVisibility(View.GONE); //隐藏通信按钮
            //提示要显示Service UUID先建立配对
            this.mtvServiceUUID.setText(getString(R.string.actMain_tv_hint_service_uuid_not_bond));
        } else {
            //已存在配对关系，建立与远程设备的连接
            this.mBDevice = this.mBT.getRemoteDevice(bluetoothInfo.getMac());
            this.showServiceUUIDs();//显示设备的Service UUID列表
            this.mbtnPair.setVisibility(View.GONE); //隐藏配对按钮
            this.mbtnComm.setVisibility(View.VISIBLE); //显示通信按钮
        }


        findViewById(R.id.btn_ignite_fid).setOnClickListener(this);
        findViewById(R.id.btn_pump_on).setOnClickListener(this);
        findViewById(R.id.btn_pump_off).setOnClickListener(this);
        findViewById(R.id.btn_reboot).setOnClickListener(this);
        findViewById(R.id.btn_detector_fid).setOnClickListener(this);
        findViewById(R.id.btn_detector_pid).setOnClickListener(this);

        showDeviceInfo();
    }


    private void initIOModel() {
        msEndFlg = msEND_FLGS[0];
        if (mBSC != null) {
            mBSC.setRxdMode(mbtInputMode);
            mBSC.setTxdMode(mbtOutputMode);
            mBSC.setReceiveStopFlg(this.msEndFlg);
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_ignite_fid:
                sendCombinationOrders(new String[]{SCREEN, PUSH_1, QUIT, LOG_START}, new int[]{0, 1000, 6000, 7000});
                break;
            case R.id.btn_reboot:
                sendCombinationOrders(new String[]{SCREEN, PUSH_EX, QUIT, LOG_START}, new int[]{0, 200, 2200, 2400});
                break;
            case R.id.btn_pump_on:
                this.Send(PUMP_ON);
                break;
            case R.id.btn_pump_off:
                this.Send(PUMP_OFF);
                break;
            case R.id.btn_detector_fid:
                this.Send(DETECTOR_FID);
                break;
            case R.id.btn_detector_pid:
                this.Send(DETECTOR_PID);
                break;
        }
    }

    /**
     * 显示选中这被的信息
     *
     * @return void
     */
    private void showDeviceInfo() {
        /*显示需要连接的设备信息*/
        actMainTvDeviceInfo.setText(
                String.format(getString(R.string.actMain_device_info),
                        bluetoothInfo.getName(),
                        bluetoothInfo.getMac(),
                        bluetoothInfo.getCod(),
                        bluetoothInfo.getRssi(),
                        bluetoothInfo.getDeviceType(),
                        bluetoothInfo.getBond()
                )
        );
        if (GlobalPoolApplication.instance.isConnect()) {
            mbtnComm.setText("断开连接");
            connectSuccess();
        }
    }


    private void connectSuccess() {
        actKeyBoard_ll_ctrl_area.setVisibility(View.VISIBLE);
        initIOModel();
        //初始化结束，启动接收线程
        new receiveTask()
                .executeOnExecutor(GlobalPoolApplication.instance.FULL_TASK_EXECUTOR);
    }


    /**
     * 显示Service UUID信息
     *
     * @return void
     */
    private void showServiceUUIDs() {
        //对于4.0.3以上的系统支持获取UUID服务内容的操作
        if (Build.VERSION.SDK_INT >= 15) {
            new GetUUIDServiceTask().execute("");
        } else {    //不支持获取uuid service信息
            this.mtvServiceUUID.setText(getString(R.string.actMain_msg_does_not_support_uuid_service));
        }
    }

    @Override
    public void getIntentData() {
        bluetoothInfo = getIntent().getParcelableExtra("BluetoothInfo");

    }

    @Override
    public BasePresent newP() {
        return new BasePresent();
    }

    @OnClick({R.id.actMain_btn_pair, R.id.actMain_btn_conn})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.actMain_btn_pair:
                new PairTask().execute(this.bluetoothInfo.getMac());
                this.mbtnPair.setEnabled(false); //冻结配对按钮

                break;
            case R.id.actMain_btn_conn:
                if (GlobalPoolApplication.instance.isConnect()) {
                    GlobalPoolApplication.instance.closeConn();
                    actKeyBoard_ll_ctrl_area.setVisibility(View.INVISIBLE);
                    setResult(Activity.RESULT_OK);
                    finish();
                } else {
                    new connSocketTask().execute(this.mBDevice.getAddress());
                }
                break;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // TODO: add setContentView(...) invocation
        ButterKnife.bind(this);
    }

    //----------------
    /*多线程处理(读取UUID Service信息线程)*/
    private class GetUUIDServiceTask extends AsyncTask<String, String, Integer> {
        /**
         * 延时等待时间
         */
        private static final int miWATI_TIME = 4 * 1000;
        /**
         * 每次检测的时间
         */
        private static final int miREF_TIME = 200;
        /**
         * uuis find service is run
         */
        private boolean mbFindServiceIsRun = false;

        /**
         * 线程启动初始化操作
         */
        @Override
        public void onPreExecute() {
            mslUuidList.clear();
            //提示UUID服务搜索中
            mtvServiceUUID.setText(getString(R.string.actMain_find_service_uuids));
            // Don't forget to unregister during onDestroy
            registerReceiver(_mGetUuidServiceReceiver,
                    new IntentFilter(BluetoothDevice.ACTION_UUID));// Register the BroadcastReceiver
            this.mbFindServiceIsRun = mBDevice.fetchUuidsWithSdp();
        }

        /**
         * 线程异步处理
         */
        @Override
        protected Integer doInBackground(String... arg0) {
            int iWait = miWATI_TIME;//倒减计数器

            if (!this.mbFindServiceIsRun)
                return null; //UUID Service扫瞄服务器启动失败

            while (iWait > 0) {
                if (mslUuidList.size() > 0 && iWait > 1500)
                    iWait = 1500; //如果找到了第一个UUID则继续搜索N秒后结束
                SystemClock.sleep(miREF_TIME);
                iWait -= miREF_TIME;//每次循环减去刷新时间
            }
            return null;
        }

        /**
         * 阻塞任务执行完后的清理工作
         */
        @Override
        public void onPostExecute(Integer result) {
            StringBuilder sbTmp = new StringBuilder();
            try {
                unregisterReceiver(_mGetUuidServiceReceiver);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //如果存在数据，则自动刷新
            if (mslUuidList.size() > 0) {
                for (int i = 0; i < mslUuidList.size(); i++)
                    sbTmp.append(mslUuidList.get(i) + "\n");
                mtvServiceUUID.setText(sbTmp.toString());
            } else//未发现UUIS服务列表
                mtvServiceUUID.setText(R.string.actMain_not_find_service_uuids);
        }
    }

    //----------------
    /*多线程处理(建立蓝牙设备的串行通信连接)*/
    private class connSocketTask extends AsyncTask<String, String, Integer> {
        /**
         * 进程等待提示框
         */
        private ProgressDialog mpd = null;
        /**
         * 常量:连接建立失败
         */
        private static final int CONN_FAIL = 0x01;
        /**
         * 常量:连接建立成功
         */
        private static final int CONN_SUCCESS = 0x02;

        /**
         * 线程启动初始化操作
         */
        @Override
        public void onPreExecute() {
            /*定义进程对话框*/
            this.mpd = new ProgressDialog(ReceiveDataActivity.this);
            this.mpd.setMessage(getString(R.string.actMain_msg_device_connecting));
            this.mpd.setCancelable(false);//可被终止
            this.mpd.setCanceledOnTouchOutside(false);//点击外部可终止
            this.mpd.show();
        }

        @Override
        protected Integer doInBackground(String... arg0) {
            if (mGP.createConn(arg0[0]))
                return CONN_SUCCESS; //建立成功
            else
                return CONN_FAIL; //建立失败
        }

        /**
         * 阻塞任务执行完后的清理工作
         */
        @Override
        public void onPostExecute(Integer result) {

            this.mpd.dismiss();
            if (CONN_SUCCESS == result) {    //通信连接建立成功
                mbtnComm.setText("断开连接"); //隐藏 建立通信按钮
                NToast.shortToast(getString(R.string.actMain_msg_device_connect_succes));
                mBSC = mGP.mBSC;
                connectSuccess();
                //初始化结束，启动接收线程
//                new receiveTask()
//                        .executeOnExecutor(GlobalPoolApplication.instance.FULL_TASK_EXECUTOR);
            } else {    //通信连接建立失败
                NToast.shortToast(getString(R.string.actMain_msg_device_connect_fail));
            }
        }
    }

    /**
     * 广播监听:获取UUID服务
     */
    private BroadcastReceiver _mGetUuidServiceReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent intent) {
            String action = intent.getAction();
            int iLoop = 0;
            if (BluetoothDevice.ACTION_UUID.equals(action)) {
                Parcelable[] uuidExtra =
                        intent.getParcelableArrayExtra("android.bluetooth.device.extra.UUID");
                if (null != uuidExtra)
                    iLoop = uuidExtra.length;
                /*uuidExtra should contain my service's UUID among his files, but it doesn't!!*/
                for (int i = 0; i < iLoop; i++)
                    mslUuidList.add(uuidExtra[i].toString());
            }
        }
    };

    //----------------
    /*多线程处理(配对处理线程)*/
    private class PairTask extends AsyncTask<String, String, Integer> {
        /**
         * 常量:配对成功
         */
        static private final int RET_BOND_OK = 0x00;
        /**
         * 常量: 配对失败
         */
        static private final int RET_BOND_FAIL = 0x01;
        /**
         * 常量: 配对等待时间(10秒)
         */
        static private final int iTIMEOUT = 1000 * 10;

        /**
         * 线程启动初始化操作
         */
        @Override
        public void onPreExecute() {
            //提示开始建立配对
            NToast.shortToast(getString(R.string.actMain_msg_bluetooth_Bonding));
            /*蓝牙自动配对*/
            //监控蓝牙配对请求
            registerReceiver(_mPairingRequest, new IntentFilter(BluetoothCtrl.PAIRING_REQUEST));
            //监控蓝牙配对是否成功
            registerReceiver(_mPairingRequest, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
        }

        @Override
        protected Integer doInBackground(String... arg0) {
            final int iStepTime = 150;
            int iWait = iTIMEOUT; //设定超时等待时间
            try {    //开始配对
                //获得远端蓝牙设备
                mBDevice = mBT.getRemoteDevice(arg0[0]);
                BluetoothCtrl.createBond(mBDevice);
                mbBonded = false; //初始化配对完成标志
            } catch (Exception e1) {    //配对启动失败
                Log.d(getString(R.string.app_name), "create Bond failed!");
                e1.printStackTrace();
                return RET_BOND_FAIL;
            }
            while (!mbBonded && iWait > 0) {
                SystemClock.sleep(iStepTime);
                iWait -= iStepTime;
            }
            return (int) ((iWait > 0) ? RET_BOND_OK : RET_BOND_FAIL);
        }

        /**
         * 阻塞任务执行完后的清理工作
         */
        @Override
        public void onPostExecute(Integer result) {
            unregisterReceiver(_mPairingRequest); //注销监听

            if (RET_BOND_OK == result) {//配对建立成功
                NToast.shortToast(getString(R.string.actMain_msg_bluetooth_Bond_Success));
                mbtnPair.setVisibility(View.GONE); //隐藏配对按钮
                mbtnComm.setVisibility(View.VISIBLE); //显示通信按钮
                bluetoothInfo.setBond(getString(R.string.actDiscovery_bond_bonded));
                GlobalPoolApplication.instance.bluetoothInfo.setBond(getString(R.string.actDiscovery_bond_bonded));
                showDeviceInfo();//刷新配置信息
                showServiceUUIDs();//显示远程设备提供的服务
            } else {    //在指定时间内未完成配对
                NToast.shortToast(getString(R.string.actMain_msg_bluetooth_Bond_fail));
                try {
                    BluetoothCtrl.removeBond(mBDevice);
                } catch (Exception e) {
                    Log.d(getString(R.string.app_name), "removeBond failed!");
                    e.printStackTrace();
                }
                mbtnPair.setEnabled(true); //解冻配对按钮
            }
        }
    }

    /**
     * 广播监听:蓝牙配对处理
     */
    private BroadcastReceiver _mPairingRequest = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            BluetoothDevice device = null;
            if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {    //配对状态改变时，的广播处理
                device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device.getBondState() == BluetoothDevice.BOND_BONDED)
                    mbBonded = true;//蓝牙配对设置成功
                else
                    mbBonded = false;//蓝牙配对进行中或者配对失败
            }
        }
    };


    /*多线程处理(建立蓝牙设备的串行通信连接)*/
    private class receiveTask extends AsyncTask<String, String, Integer> {
        /**
         * Constant: the connection is lost
         */
        private final static byte CONNECT_LOST = 0x01;
        /**
         * Constant: the end of the thread task
         */
        private final static byte THREAD_END = 0x02;

        /**
         * 线程启动初始化操作
         */
        @Override
        public void onPreExecute() {
            receiveTv.setText(getString(R.string.msg_receive_data_wating));
            mbThreadStop = false;
        }

        /**
         * 线程异步处理
         */
        @Override
        protected Integer doInBackground(String... arg0) {
            if (null != mBSC) {
                mBSC.Receive(); //首次启动调用一次以启动接收线程
            }

            while (!mbThreadStop) {
                NLog.d("receiveTask", TAG + "接收数据");
                if (null != mBSC && !mBSC.isConnect())//检查连接是否丢失
                    return (int) CONNECT_LOST;

                if (null != mBSC && mBSC.getReceiveBufLen() > 0) {
                    SystemClock.sleep(20); //先延迟让缓冲区填满
                    this.publishProgress(mBSC.Receive());
                }
            }
            return (int) THREAD_END;
        }

        /**
         * 线程内更新处理
         */
        @Override
        public void onProgressUpdate(String... progress) {
            if (null != progress[0]) {
                receiveTv.append(progress[0]); //显示区中追加数据
                autoScroll(); //自动卷屏处理
            }
        }

        /**
         * 阻塞任务执行完后的清理工作
         */
        @Override
        public void onPostExecute(Integer result) {
            if (CONNECT_LOST == result) //connection is lost
                receiveTv.append(getString(R.string.msg_msg_bt_connect_lost));
            else {
//                receiveTv.append(getString(R.string.msg_receive_data_stop));//Tip receive termination
            }
        }
    }

    /**
     * 自动滚屏的处理
     *
     * @return void
     */
    private void autoScroll() {
        int iOffset = 0;
        //自动滚屏处理
        iOffset = this.receiveTv.getMeasuredHeight() - this.receiveTv.getHeight();
        if (iOffset > 0)
            this.receiveTv.scrollTo(0, iOffset);

    }

    @Override
    public void onBackPressed() {
        this.mbThreadStop = true; //终止接收线程
        setResult(Activity.RESULT_OK);
        finish();
    }

    @Override
    protected void onDestroy() {
        this.mbThreadStop = true; //终止接收线程
        super.onDestroy();
    }

    @Override
    public boolean isNotWorkConnect() {
        return false;
    }


    private void Send(String var1) {
        if (!var1.equals("")) {
            if (var1.equals("log start") && this.mProgressDialog != null && this.mProgressDialog.isShowing()) {
                this.mProgressDialog.dismiss();
            }

            int var2;
            if (!this.msEndFlg.isEmpty()) {
                var2 = this.mBSC.Send(var1.concat(this.msEndFlg));
            } else {
                var2 = this.mBSC.Send(var1);
            }

            if (var2 >= 0) {
                if (var2 == 0) {
                    NToast.showToast(this, "指令发送失败", 1);
//                    this.mtvSendView.append(var1.concat("(fail) "));
                } else {
                    NToast.showToast(this, "指令发送成功", 1);
//                    this.mtvSendView.append(var1.concat("(succeed) "));
                }
            } else {
                NToast.showToast(this, getString(R.string.msg_msg_bt_connect_lost), 1);
            }

        }

    }

    private void sendCombinationOrders(String[] instructs, int[] times) {
//        int var3 = 0;
        this.mProgressDialog = ProgressDialog.show(this, "", "正在发送指令", false, false);
//        int var4 = 0;

        for (int i = 0; i < instructs.length; i++) {
            final String intstruct = instructs[i];
            this.mHandler.postDelayed(new Runnable() {
                public void run() {
                    Send(intstruct);
                }
            }, times[i]);
        }

//        for(int var5 = instructs.length; var3 < var5; ++var3) {
//            final String intstruct = instructs[var3];
//            this.mHandler.postDelayed(new Runnable() {
//                public void run() {
//                    Send(intstruct);
//                }
//            }, (long)times[var4]);
//            ++var4;
//        }

    }
}
